# -*- coding:utf-8 -*-
# @Author : felix

# 专门存放关键字的文件，把所有常用的接口请求过程当中的操作都存在在这个位置
# 面向对象的思路


# 考虑 1.发送post，get

"""
可添加@allure.step(“描述信息”)

"""
import requests
import allure
import json
import jsonpath
from PytestApi.apirun_v7.core.globalContext import g_context




class KeyWords:

    @allure.step("参数数据: 发送post请求")
    def request_post(self,**kwargs):
        response = requests.post(**kwargs)
        g_context().set_dict("current_response", response)
        # 将响应结果添加到 Allure 报告
        allure.attach(response.text, name='Response', attachment_type=allure.attachment_type.TEXT)

        return response

    @allure.step("参数数据: 发送post请求")
    def request_post_form_urlencoded(self,**kwargs):

        """
        发送post 请求
        :param kwargs:
        :return:
        """
        url = kwargs.get('域名', None)
        params = kwargs.get("URL参数",None)
        headers = kwargs.get("请求头",None)
        data = kwargs.get("请求数据",None)

        requests_data = {
            "url": url,
            "params": params,
            "headers": headers,
            "data": data
        }

        response = requests.post(**requests_data)
        # 将返回的对象加入全局变量中
        g_context().set_dict("current_response", response)
        # 将响应结果添加到 Allure 报告
        allure.attach(response.text, name='Response', attachment_type=allure.attachment_type.TEXT)

        return response

    @allure.step("参数数据: 发送post请求")
    def request_post_json(self,**kwargs):

        """
        发送post 请求
        :param kwargs:
        :return:
        """
        url = kwargs.get('域名', None)
        params = kwargs.get("URL参数",None)
        headers = kwargs.get("请求头",None)
        data = kwargs.get("请求数据",None)

        requests_data = {
            "url": url,
            "params": params,
            "headers": headers,
            "json": data
        }

        response = requests.post(**requests_data)
        # 将返回的对象加入全局变量中
        g_context().set_dict("current_response", response)
        # 将响应结果添加到 Allure 报告
        allure.attach(response.text, name='Response', attachment_type=allure.attachment_type.TEXT)

        return response



    @allure.step("参数数据: 发送Get请求")
    def request_get(self, **kwargs):

        url: None = kwargs.get('域名', None)
        params = kwargs.get("URL参数",None)
        headers = kwargs.get("请求头",None)
        data = kwargs.get("请求数据",None)

        requests_data = {
            "url": url,
            "params": params,
            "headers": headers,
            "json": data
        }


        response = requests.get(**requests_data)
        g_context().set_dict("current_response", response)
        # 将响应结果添加到 Allure 报告
        allure.attach(response.text, name='Response', attachment_type=allure.attachment_type.TEXT)

        return response

    @allure.step("参数数据: 提取JSON数据并存储到全局变量")
    def ex_jsonData(self,**kwargs):
        """
        提取Json数据
        1. 提取的数据是什么？  ---一般提取的都是响应数据
        2. 提取的表达式是什么？
        3. 提取的下标是什么？
        4. 保存到全局的变量名是什么？

        :param EXVALUE: 提取json的表达式
        :param  INDEX: 下标
        :param VARNAME:  存储到全局变量的变量名
        :return:
        """

        # TODO 1 : 获取响应数据
        response = g_context().get_dict("current_response").json()

        print("对应响应:",response)

        # TODO 2 : 拿到对应的提取表达式
        EXVALUE = kwargs.get('EXVALUE', None)

        # TODO 3 : 拿到对应下标
        INDEX = kwargs.get('INDEX', 0)

        if EXVALUE is None:
            INDEX = 0

        # 提取数据
        ex_data = jsonpath.jsonpath(response, EXVALUE)[INDEX]

        print(ex_data)

        # TODO 4 : 通过提取的数据存储成对应变量到全局变量中
        g_context().set_dict(kwargs["VARNAME"], ex_data)

        print("--------------------")
        print("全局变量中的数据:",g_context().show_dict())
        print("--------------------")
        return ex_data

    @allure.step("断言处理: 通过响应数据进行断言")
    def assert_text_comparators(self, **kwargs):
        """
        :param EXPECTED:  期望结果
        :param VALUE: 实际结果
        :param OP_STR: 比较运算符: > = <
        :return:
        """
        # 字典 + 匿名函数 : lambda 需要传的参数: 执行的操作
        comparators = {
            # key :value
            # 操作符是A: 执行A
            ">": lambda a,b: a>b,
            ">=": lambda a,b: a>=b,
            "<": lambda a,b: a<b,
            "<=": lambda a,b: a<=b,
            "!=": lambda a,b: a!=b,
            "==": lambda a,b: a==b
        }
        if kwargs["OP_STR"] not in comparators:
            raise ValueError(f"没有改操作方式:{kwargs['OP_STR']}")

        if not comparators[kwargs["OP_STR"]](kwargs["EXPECTED"], kwargs["VALUE"]):
            # 返回是false才会进入
            raise AssertionError(f'期望值:{kwargs["EXPECTED"]} {kwargs["OP_STR"]} 实际值:{kwargs["VALUE"]}')
